import {
  postLogin,
  getInfoDetails,
  changeDept,
  oauthLogout,
} from "@/api/login";
import { getRolseAPPKey, getRolseConfig } from "@/king-components/js/App.js";
import config from "@/common/config";
import { Md5 } from "ts-md5";
const user = {
  namespaced: true,
  state: {
    userInfo: uni.getStorageSync("__APP__userInfo") || {},
    // roleInfo 为当前所选角色信息（用户可能会有多角色）
    roleInfo: uni.getStorageSync("__APP__roleInfo") || {},
    token: uni.getStorageSync("__APP__token") || "",
    currdeptInfo: uni.getStorageSync("__APP__currdeptInfo") || {},
    loginInfo: uni.getStorageSync("__APP__loginInfo") || {},
  },
  actions: {
    /** 刷新token登录 */
    async refreshToken({ commit, state }, data = {}) {
      uni.showLoading({
        title: "加载中",
      });
      const { refresh_token, deptid } = state.loginInfo;
      // const useRoleId = state.roleId;
      const { deptId, roleId } = data;

      try {
        const pam = {
          tenantId: config.tenantId,
          refresh_token: refresh_token,
          grant_type: "refresh_token",
          scope: "all",
        };
        const postDeptId = deptId || deptid; // 提交的deptId
        const postRoleId = roleId || state.roleInfo.id; // 提交的roleId

        const loginData = {
          "Dept-Id": postDeptId,
          "Role-Id": postRoleId /** 默认不更换角色 */,
        };

        const res = await changeDept(pam, loginData);
        // 先设置token
        commit("setToken", res.access_token);

        // 再处理用户信息和后续信息
        const userDetails = await getInfoDetails();
        if (!userDetails.data) throw new Error("获取用户信息失败");
        const { user /* , roles */ } = userDetails.data;
        commit("setUserInfo", user);

        // 设置当前部门
        let currDept = user.dept.find((item) => item.id == postDeptId);
        if (!currDept) {
          currDept = user.dept[0];
        }
        // 兼容处理 (getInfo 和 info 返回的字段不一致)
        currDept.deptId = currDept.id;
        commit("setCurrdeptInfo", currDept);
        // 设置当前角色
        let currRole = user.roles.find((item) => item.id == postRoleId);
        if (!currRole) {
          currRole = user.roles[0];
        }
        // 兼容处理 (getInfo 和 info 返回的字段不一致)
        currRole.roleId = currRole.id;
        currRole.name = currRole.roleName;
        commit("setRole", currRole);

        commit("setLoginInfo", {
          deptid: res.dept_id,
          refresh_token: res.refresh_token,
          account: res.account
        });
        uni.hideLoading();
        return { currRole, currDept, loginInfo: res, userInfo: user };
      } catch (error) {
        console.error(error);
        uni.hideLoading();
        uni.showToast({
          title: error.message || "重登失败",
          duration: 2000,
          icon: "error",
        });
        return error;
      }
    },
    /** 登出  */
    async logout({ commit, dispatch, state } /* context */, data) {
      try {
        // 调用接口退出登录
        await oauthLogout();
      } catch (error) {
        // 调用接口失败不要阻止用户退出
        console.warn("退出登录请求失败", error);
      }

      state.token = "";
      state.userInfo = {};
      state.roleInfo = {};
      state.currdeptInfo = {};

      uni.removeStorageSync("__APP__userInfo");
      uni.removeStorageSync("__APP__token");
      uni.removeStorageSync("__APP__roleInfo");
      // 删除部门选择信息代表本次用户选择的部门信息，重新登录需要重新选择
      uni.removeStorageSync("__APP__currdeptInfo");
      // 删除角色信息
      uni.removeStorageSync("__APP__roleInfo");

      // 清理字典数据
      uni.removeStorageSync("__APP__Dict");

      // 业务模块的登出处理
      commit("business/onLogout", {}, { root: true });

      if (data?.isReLaunch) {
        uni.reLaunch({
          url: "/pages/subHome/login/login",
        });
      }
    },
    /** 账号登录 */
    async login({ commit, dispatch }, data) {
      const { username, password } = data;
      try {
        uni.showLoading({ title: "登录中..." });
        const pam = {
          username,
          password: Md5.hashStr(password),
        };
        const loginRes = await postLogin(pam);
        // console.log("dispatch -> login:res", loginRes);
        if (loginRes.error_description) {
          return loginRes.error_description == "Bad credentials"
            ? uni.showToast({ title: "用户名或密码错误", icon: "none" })
            : uni.showToast({
                title: loginRes.error_description,
                icon: "none",
              });
        }
        if (!loginRes.role_id) {
          return uni.showToast({ title: "你无权登录该系统！", icon: "none" });
        }
        await dispatch("initUserInfo", loginRes);
      } catch (error) {
        console.error(error);
        uni.hideLoading();
        uni.showToast({
          title: error.message || "登录失败",
          duration: 2000,
          icon: "error",
        });
      }
    },
    /* 登录成功执行获取用户数据/保存token等操作 */
    async initUserInfo({ commit, dispatch }, data) {
      // 请求登录成功先保存token （后续getInfo需要）
      commit("setToken", data.access_token);

      try {
        uni.showLoading({
          title: "获取用户信息中...",
        });
        const userDetails = await getInfoDetails();
        if (!userDetails.data) throw new Error("获取用户信息失败");
        const { user /* , roles */ } = userDetails.data;

        uni.hideLoading();

        // 获取用户角色信息 （user.role 包含角色对象信息）
        // 1. 过滤，只显示 APP.js 中配置的角色
        const trueRoleList = user.roles.filter((r) => {
          const role = getRolseConfig(r.roleAlias);
          return !!role;
        });
        // 2.如果有多个角色，则跳转选角色
        if (trueRoleList.length > 1) {
          uni.navigateTo({
            url: "/pages/subSetting/switchRole/index?mode=select",
            success: () => {
              // 创建事件监听
              uni.$on("login:role-select", async (item) => {
                console.log("///// login:role-select //////", item);

                // 下同
                // 存储当前角色信息 和 登录信息 （刷新token时需要这些数据）
                const currRole = trueRoleList[0];
                commit("setRole", currRole);
                commit("setLoginInfo", data);

                // 调用接口设置角色刷新token
                await dispatch("refreshToken", {});
                uni.reLaunch({ url: "/pages/subHome/globalHomePage/index" });

                // 跳转首页
              });
            },
          });
        } else if (trueRoleList.length == 1) {
          // 3.单角色则直接选择角色/部门进行设置

          // 存储当前角色信息 和 登录信息 （刷新token时需要这些数据）
          const currRole = trueRoleList[0];
          commit("setRole", currRole);
          commit("setLoginInfo", data);

          // 调用接口设置角色刷新token
          await dispatch("refreshToken", {});

          // 跳转首页
          uni.reLaunch({ url: "/pages/subHome/globalHomePage/index" });
        } else {
          uni.showToast({ title: "当前账号无法登录该平台", icon: "none" });
        }
      } catch (error) {
        console.error("获取用户信息失败#1", error);
        // 取消监听
        uni.$off("login:role-select");
      }
    },
  },
  mutations: {
    /** 设置角色数组 */
    setRole(state, data) {
      state.roleInfo = data;
      uni.setStorageSync("__APP__roleInfo", data);
    },
    /** 登录 (暂时不用) */
    login(state, data) {
      state.userInfo = data.userDto;
      uni.setStorageSync("__APP__userInfo", data.userDto);
    },
    setUserInfo(state, data) {
      state.userInfo = data;
      // console.log(" uni.setStorageSyn userInfo",  data);
      uni.setStorageSync("__APP__userInfo", data);
    },
    /** 设置 Token */
    setToken(state, token, refresh_token) {
      state.token = token;
      uni.setStorageSync("__APP__token", token);
    },
    /** 重置 Token */
    resetToken(state) {
      state.token = "";
      uni.removeStorageSync("__APP__token");
    },
    /** 设置登录信息（暂无用途） */
    setLoginInfo(state, loginInfo) {
      state.loginInfo = loginInfo;
      uni.setStorageSync("__APP__loginInfo", loginInfo);
    },
    /** 设置当前登录的部门信息 */
    setCurrdeptInfo(state, currdeptInfo) {
      // console.log("xxxx", currdeptInfo);
      state.currdeptInfo = currdeptInfo;
      uni.setStorageSync("__APP__currdeptInfo", currdeptInfo);
    },
  },
};
export default user;
